爱番番反哺SkyWalking构建开源APM网格
全文约4600字,预计阅读时间10分钟
1. 可观察的挑战
爱番番作为一站式智能营销和销售的加速器,旨在助力企业实现业务增长。而在ToB SaaS行业中面临着激烈的竞争情况下,业务稳定性与客户满意度是业务成功的前提,而服务的可观察性又是一切用户体验提升的前提。
可观察性作为云原生核心要素之一,主要由以下三大支柱构成,分别是Logging(日志),Metrics(指标),以及Tracing(应用跟踪)。
Logging:展现的是应用运行而产生的事件或者程序在执行的过程中间产生的一些日志,可以详细解释系统的运行状态,但是存储和查询需要消耗大量的资源。
Metrics:是一种聚合数值,存储空间很小,可以观察系统的状态和趋势,但对于问题定位缺乏细节展示。
Tracing:面向的是请求,可以轻松分析出请求中异常点,但与Logging有相同的问题就是资源消耗较大。
在2020.2-2020.6 爱番番服务迁移Kubernetes中,爱番番团队基于CNCF以及Apache等组织提供了大量可观察领域开源项目搭建了业界常用的可观察数据采集服务,整体上符合上随着业务增长以及TOB下的业务逻辑复杂,单机下数据采集的效率与数据丢失问题日益凸现。如Java日志天然包含大量的异常堆栈,导致存在Fluentd 单核采集性能由官方宣称的5000OPS退化为2500OPS问题。上述可观察职责划分,对于Tracing、Metrics、以及Logging分不同的渠道进行采集,但回顾过去一年的实践经验,不可否认,以下问题贯穿始终:
多条计算流并存:如何整合以减少资源与维护成本?
如何控制资源成本:随着爱番番用户的不断增加,APM数据采集采集的规模也不断扩大,带来的资源成本花销也不断扩大。
多语言性接入方:存在着Java、Golang、Nodejs、Python等语言。
网络拓扑复杂:存在着与大商业多个部门以及内部180+模块直接的复杂依赖关系,如何以轻量级模式支持各类业务打点需求,且避免引入Smart-Client。
数据稳定性:随着业务增长以及TOB下的业务逻辑复杂,单机下数据采集的效率与数据丢失问题日益凸现。如Java日志天然包含大量的异常堆栈,导致存在Fluentd 单核采集性能由官方宣称的5000OPS退化为2500OPS问题。
2. APM网格思路下的数据采集整合
2.1 艰难的抉择
为了解决以上问题,我们展开了数次讨论,希望有办法找到一种方案进行Logging,Tracing 以及Metrics的一站式融合采集,且具有良好的性能与稳定性。但从目前的开源生态下看,目前存在以下问题:
CNCF下虽然可观察项目百花齐放,并无覆盖Logging,Tracing,以及Metrics的统一完整解决方案。
OpenTelemetry项目尚处于早期阶段,无法覆盖Logging场景,且在主要定位为桥接层的目标下,暂未统一可观察计算端的目标。
但从ROI与私有化/多云部署等方面来看,开源项目是目前我们较好的选择,我们不但可以集中更多资源投入业务迭代中,又可以不断的获得来自上游的开源红利,最终所以经过了层层讨论和论述,最终的答案明亮起来,爱番番团队与Apache SkyWalking以及Apache ApiSix 团队进行合作,共同构建了Apache SkyWalking Satellite子项目,并由爱番番团队负责核心结构设计。
爱番番团队,SkyWalking团队与ApiSix 团队能达成此次三方的合作,也是在具有良好生产落地使用经验与历史开源合作的基础上,同时对未来SkyWalking的产品的发展具有信心:
SkyWalking 目前已经在爱番番大规模部署使用,且运行稳定,不但满足了调用链,流量拓扑,指标查看等基础功能,而且支持了爱番番流量染色分析等业务需求。
开源贡献方面爱番番向Apache SkyWalking 主库贡献28次,涉及采集、计算、存储等多方面特性贡献,目前团队存在2名Apache SkyWalking Committer。
SkyWalking 已经原生支持了Trace以及Metric的分析,且SkyWalking 有规划支持Logging,可以预见SkyWalking作为统一APM分析端的可行性。
SkyWalking 从协议上虽然没有遵循原生Dapper论文中的模型,略微增加了Client端传输负载, 但解放了服务端计算压力,使得服务端可以自由水平扩展,而无需关心细节数据的分组聚合,这对TOB Saas 场景更加适合。
对于已经选择的Service Mesh 产品Istio,我们希望现有其他产品可以与其更好的融合,而Istio、Envoy 和 Apache SkyWalking 的作者Zack Butcher、周礼赞和吴晟恰好来自于同一家公司,可以预见SkyWalking社区与Istio社区将进行更多的特性支持互动。
2.2 目标
针对以上问题,三方团队希望Satellite项目的建立能达成以下目标:
希望Satellite作为一个高性能的数据采集与预处理工具,将SkyWalking 打造为提供一站式覆盖Tracing、Logging 以及Metrics 的产品。
希望以下沉的手段将多语言Agent的重复开发任务解放,将共性功能如缓存、MQ交互等统一下沉于Satellite。
希望Satellite具有由拉转推的能力(如Prometheus 数据采集),这将提升公网环境下得数据传输安全。
希望预处理手段的加入可以将Metrics,Logging,以及Tracing进行更多融合,如本地级别采样,在保证Metrics精准的同时降低网络传输负载。
希望Satellite具有良好的扩展性,可以易于以插件模式增强私有化特性。
2.3 设计思路
面对以上目标,当以SIdecar 思维去设计一个APM 网格的边缘代理时,以下问题摆在了我们的面前:
APM采集数据较多,如何降低资源消耗?
与ServiceMesh不同,APM很多数据无法做到真正的与用户进程彻底隔离,比如假如调用链信息包含用户方法等,这又如何避免Smart Client,做到快速升级?
如何保证数据稳定且兼顾效率?
如何降低后续开发成本,让更多的人参与贡献?
我们的选择如下:
语言选择是使用纯Go开发,避免类似Java语言带来的大量内存消耗。
所有语言上将与MQ的发送能力与数据稳定性保证下沉于Sidecar,提供给用户一个轻量级SDK,做到快速集成与升级,针对如Java这种JVM语言,甚至可以做到提供给用户一个空SDK,将发送逻辑下沉于JavaAgent,做到APM采集于业务的彻底解耦。
在数据稳定性上,提供基于MMAP映射的文件队列,做到容量,资源,容灾与效率的同时兼顾。
架构模型上和主库的SkyWalking一样,完全采用微核架构模式进行开发,降低插件贡献成本。
2.4 微核架构设计
出于让功能开发更简单的目标,Satellite整体设计上采用微核架构的思想进行设计,内核(core)只包含系统运行的最小功能,主要负责编排插件,而插件则是独立的。
Core System是数据宏观上的处理流程,主要包含三部分:
Gatherer:数据采集器,以Fetch或Receive的模式进行数据接收。
Processor:数据处理器,负责数据模式的转化,如由Tracing或Logging数据生成Metrics。
Sender:数据发送器,以MQ或gRPC等发送模式进行数据上行。
而Plugins以接口的方式扩展于Core System,目前包含7类插件,可以分为共享型插件,私有型插件与通用功能插件:
共享型插件:
Client:负责与MQ或其他通路进行连接,可以被多个Pipe中的Sender所共享。(Pipe:Satellite中每一条数据采集通路称为Pipe)
Server:负责数据的接收,主要被多个Pipe中的Gatherer插件进行共享。
私有型插件:
Fetcher:负责数据的拉取,如Prometheus Fetcher,Log Fetcher等。
Receiver:负责数据的接收,如通过gRPC上行的SkyWalking Trace数据或用户的日志数据。
Queue:负责数据的缓冲,如文件队列或内存队列等。
Filter:以链式结构作用于Processor中,为预处理提供可能。
Forwarder:数据转发器,负责数据上行。
通用功能插件:
Parser:负责通用数据解析,如csv解析器等。
Fallbacker:数据发送回退策略,可以与Forwarder插件配合使用。
2.5 数据稳定性设计
从上面的插件设计中可以看到,Satellite 同时支持Fetch模式与Receive模式,而不仅仅面对着文件的采集,这就存在这以下问题:
出口阻塞,如何容灾?
文件模式需要经过内核态与用户态,效率如何保证?
如何避免数据回溯带来的索引膨胀?
针对以上问题,我们进行了如下思考:
出于容灾与资源方面的考虑,数据持久化磁盘是必然的选择。
如果使用内存磁盘映射,避免写文件时同时经过内核态与用户态,应该可以进行效率的提升。
Kafka的Offset 设计带来的好处是数据可以随机访问,可以类比于磁盘访问数据,但是我们的场景更像是磁带场景,数据需要大规模存储,读取是有序的,因此可以使用弱索引的的设计避免索引机制带来的资源二次消耗。
所以MMAP队列结构上主要包含2部分:数据存储部分Segments与元数据索引部分Meta。
Segments从物理上看是许多相同大小基于MMAP映射的的磁盘文件,他们通过置换算法进行MMAP映射调整, 从而保证有限的内存下,将队列首尾置于内存,而队列中间的文件存储于磁盘,从而做到效率与资源消耗的平衡。
Meta部分是数据容灾的核心部分,主要包含4种Offset:
Writing Offset:记录数据写入的位置。
Watermark Offset:记录数据真正保存到磁盘的位置。
Reading Offset:记录数据读出的位置。
Committed Offset:记录数据真正发出的位置
当Satellite重启时,Satellite 将基于Meta 中的Offset 恢复整个MMAP队列,同时将Watermark Offset和Committed Offset分别作为Writing Offset与Reading Offset,最终保证数据的至少一次发送。
2.6 性能
上文曾提到,Satellite的单数据采集通道采用串行方式运行,但从以下为Satellite 0.1.0 版本性能测试报告可以看出,Satellite具有很好的数据采集能力,0.5核资源下在纯内存与MMAP条件下分别可以支持3000OPS与1600OPS的性能,相关测试数据如下:
Qps | 队列 | stack memory | heap memory | no-heap memory |
3000 | Memory | 3.34M | 28M | 83K |
1600 | MMAP | 2.62M | 13.3M | 83K |
3. 线上收益
3.1 APM网格收益
爱番番作为ToB服务的核心在于为客户提供线索,线索时效性是核心的业务指标,因此采用打点的模式进行时效监测,而其中的关键问题在于分布式环境下数据先后顺序不一以及接收机器不一等问题。而在拥有APM网格Satellite的情况下,我们使用Satellite在采集端做到数据的聚合,具体解决思路如下:
提供业务轻量级REST API,供各个语言自行实现接入。
为每一个接入方POD 自动挂载Satellite Sidecar。
业务POD通过轻量的HTTP REST协议上报打点数据。
Satellite 依靠MMAP机制进行数据稳定性保证。
Satellite Forwarder 插件通过Hash(Event ID) 选定Partition,做到逻辑分发。
消费端无需二次聚合处理,由分发机制保证同一ID的数据会由一个后端服务处理。
3.2 数据稳定性收益
在2021年1-2月份,爱番番内部进行了多次Satellite线上试点,最终将爱番番API网关日志接入Satellite,以2021.03.09 14:00-15:00数据为例,数据收集率显著上升:
对比源 | 日志总量 | 与基准差值 |
基准网关数据 | 104153537 | 0 |
Satellite数据采集 | 104027632 | 125905 |
其他日志采集器 | 76645504 | 27508003 |
后期分析差异原因如下:
Satellite 与基准差异的原因主要是单条日志大于20KB,被日志丢失策略所过滤。
其他日志采集器与基准差异过大的原因主要是目前的采集行为为标准输出流读取,且部署模式为Daemonset,提供的CPU资源为1核,采集器一般同时服务2-3个业务应用,但是大部分CPU资源被花费到Java多行日志拼接所消耗,导致性能不足。
如同样改为RPC形式进行发送,Satellite所拥有的优势为借助SkyWalking Agent已有的探针数据采集能力,给用户提供轻量级SDK,平台方可以通过Jar包版本控制工具以及Agent升级模式进行快速升级,做到彻底解耦业务与平台提供方。
4. 展望
基于预处理对Tracing,Logging 以及Metrics之间的纬度转化是Satellite APM 网格项目建立的核心要素之一,以下篇幅我们将针对预处理场景进行展望,说明预处理对业务的核心价值。
4.1 采样率展望
APM数据的量是巨大的,因此采样率是APM系统不可避免的一个话题,针对SkyWalking Trace场景,我们从客户端采样与服务端采样的角度考虑这个问题:
客户端采样:减少数据传输消耗,保证必要的细节片段,但是无法基于客户端采用后的数据准确反应客户端真实的QPS,SLA等数据,对于客户价值是有损的。
服务端采样:数据需要传输到计算端,因此需要大量资源服务于传输与数据接收,虽然可以减少存储消耗,但是无法降低计算资源。
Satellite对于采样的意义在于几乎可以避免无效的数据传输,减少资源损耗,又可以从源头产生Metrics指标,进而做到同时兼顾资源成本控制与指标准确性保证。
4.2 日志报警
随着SkyWalking 8.5.0 的发布,在ES 存储上将进行存储模式的变更,进而解决目前随Metrics指标增长带来的Shards的增长问题,从而SkyWalking可以承担更多Metrics Server的职责,我们可以进行以下尝试,在复用已有SkyWalking OAP流计算以及报警的能力下,在Satellite侧进行基于LOG的指标解析,从而快速实现日志报警等业务需求。
5. 总结
Satellite依靠灵活的微核架构设计与高性能正在服务于爱番番,SkyWalking 以及APM 开源生态。
对于爱番番自身来说,Satellite已经成为性能数据收集最好的手段,将覆盖延迟打点,CDP打点,Prometheus 指标采集,日志,链路追踪等多个领域,将采集端进行统一整合,提升研发效率。
对于Apache SkyWalking,Satellite成为了SkyWalking边缘数据采集的核心组件,将对于SkyWalking资源的控制与使用场景等方面产生积极作用,使得SkyWalking 率先成为覆盖Logging,Tracing 与Metrics全场景的开源APM解决方案。
6. 作者介绍
Evan,Apache SkyWalking Committer,Apache SkyWalking Satellite核心作者,在百度爱番番负责云原生可观察产品的研发与落地, 擅长分布式与APM相关领域。
7. 往期精选